home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / javax / swing / JLayeredPane.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  25.7 KB  |  718 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)JLayeredPane.java    1.32 98/08/28
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package javax.swing;
  15.  
  16. import java.awt.Component;
  17. import java.util.Hashtable;
  18. import java.awt.Color;
  19. import java.awt.Graphics;
  20. import java.awt.Rectangle;
  21.  
  22. import javax.accessibility.*;
  23.  
  24. /**
  25.  * JLayeredPane adds depth to a JFC/Swing container, allowing components to overlap 
  26.  * each other when needed. An Integer object specifies each component's depth in the
  27.  * container, where higher-numbered components sit "on top" of other 
  28.  * components.
  29.  * <P>
  30.  * <TABLE ALIGN="RIGHT" BORDER="0">
  31.  * <TR>
  32.  *   <TD ALIGN="CENTER">
  33.  *     <P ALIGN="CENTER"><IMG SRC="doc-files/JLayeredPane-1.gif" WIDTH="269" HEIGHT="264" ALIGN="BOTTOM" BORDER="0">
  34.  *   </TD>
  35.  * </TR>
  36.  * </TABLE>
  37.  * For convenience, JLayeredPane divides the depth-range into several different 
  38.  * layers. Putting a component into one of those layers makes it easy to ensure 
  39.  * that components overlap properly, without having to worry about specifying
  40.  * numbers for specific depths:
  41.  * <DL>
  42.  *    <DT><FONT SIZE="2">DEFAULT_LAYER</FONT></DT>
  43.  *         <DD>The standard layer, where most components go. This the bottommost 
  44.  *         layer.
  45.  *    <DT><FONT SIZE="2">PALETTE_LAYER</FONT></DT>
  46.  *         <DD>The palette layer sits over the default layer. Useful for floating 
  47.  *         toolbars and palettes, so they can be positioned above other components.
  48.  *    <DT><FONT SIZE="2">MODAL_LAYER</FONT></DT>
  49.  *         <DD>The layer used for modal dialogs. They will appear on top of any
  50.  *         toolbars, palettes, or standard components in the container.
  51.  *    <DT><FONT SIZE="2">POPUP_LAYER</FONT></DT>
  52.  *         <DD>The popup layer displays above dialogs. That way, the popup windows 
  53.  *         associated with combo boxes, tooltips, and other help text will appear 
  54.  *         above the component, palette, or dialog that generated them.
  55.  *    <DT><FONT SIZE="2">DRAG_LAYER</FONT></DT>
  56.  *         <DD>When dragging a component, reassigning it to the drag layer ensures 
  57.  *         that it is positioned over every other component in the container. When 
  58.  *         finished dragging, it can be reassigned to its normal layer.
  59.  * </DL>
  60.  * The JLayeredPane methods <code>moveToFront(Component)</code>, 
  61.  * <code>moveToBack(Component)</code> and <code>setPosition</code> can be used 
  62.  * to reposition a component within its layer. The <code>setLayer</code> method 
  63.  * can also be used to change the component's current layer.
  64.  *
  65.  * <h2>Details</h2>
  66.  * JLayeredPane manages it's list of children like Container, but
  67.  * allows for the definition of a several layers within itself. Children
  68.  * in the same layer are managed exactly like the normal Container object,
  69.  * with the added feature that when children components overlap, children 
  70.  * in higher layers display above the children in lower layers.
  71.  * <p>  
  72.  * Each layer is a distinct integer number. The layer attribute can be set 
  73.  * on a Component by passing an Integer object during the add call.<br>
  74.  * For example:
  75.  * <PRE>
  76.  *     layeredPane.add(child, JLayeredPane.DEFAULT_LAYER);
  77.  * or
  78.  *     layeredPane.add(child, new Integer(10));
  79.  * </PRE>
  80.  * The layer attribute can also be set on a Component by calling<PRE>
  81.  *     layeredPaneParent.setLayer(child, 10)</PRE>
  82.  * on the JLayeredPane that is the parent of component. The layer
  83.  * should be set <i>before</i> adding the child to the parent.
  84.  * <p>
  85.  * Higher number layers display above lower number layers. So, using 
  86.  * numbers for the layers and letters for individual components, a
  87.  * representative list order would look like this:<PRE>
  88.  *       5a, 5b, 5c, 2a, 2b, 2c, 1a </PRE>
  89.  * where the leftmost components are closest to the top of the display.
  90.  * <p>
  91.  * A component can be moved to the top or bottom position within its
  92.  * layer by calling <code>moveToFront</code> or <code>moveToBack</code>.
  93.  * <p>
  94.  * The position of a component within a layer can also be specified directly.
  95.  * Valid positions range from 0 up to one less than the number of 
  96.  * components in that layer. A value of -1 indicates the bottommost
  97.  * position. A value of 0 indicates the topmost position. Unlike layer
  98.  * numbers, higher position values are <i>lower</i> in the display.
  99.  * <blockquote> 
  100.  * <b>Note:</b> This sequence (defined by java.awt.Container) is the reverse 
  101.  * of the layer numbering sequence. Usually though, you will use <code>moveToFront</code>,
  102.  * <code>moveToBack</code>, and <code>setLayer</code>.
  103.  * </blockquote>
  104.  * Here are some examples using the method add(Component, layer, position):
  105.  * Calling add(5x, 5, -1) results in:<PRE>
  106.  *       5a, 5b, 5c, 5x, 2a, 2b, 2c, 1a </PRE>
  107.  *
  108.  * Calling add(5z, 5, 2) results in:<PRE>
  109.  *       5a, 5b, 5z, 5c, 5x, 2a, 2b, 2c, 1a </PRE>
  110.  *
  111.  * Calling add(3a, 3, 7) results in:<PRE>
  112.  *       5a, 5b, 5z, 5c, 5x, 3a, 2a, 2b, 2c, 1a </PRE>
  113.  *
  114.  * Using normal paint/event mechanics results in 1a appearing at the bottom
  115.  * and 5a being above all other components.
  116.  * <p>
  117.  * <b>Note:</b> that these layers are simply a logical construct and LayoutManagers
  118.  * will affect all child components of this container without regard for
  119.  * layer settings.
  120.  * <p>
  121.  * <strong>Warning:</strong>
  122.  * Serialized objects of this class will not be compatible with 
  123.  * future Swing releases.  The current serialization support is appropriate
  124.  * for short term storage or RMI between applications running the same
  125.  * version of Swing.  A future release of Swing will provide support for
  126.  * long term persistence.
  127.  * 
  128.  * @version 1.32 08/28/98
  129.  * @author David Kloba
  130.  */
  131. public class JLayeredPane extends JComponent implements Accessible {
  132.     /// Watch the values in getObjectForLayer()
  133.     /** Convenience object defining the Default layer. Equivalent to new Integer(0).*/
  134.     public final static Integer DEFAULT_LAYER = new Integer(0);
  135.     /** Convenience object defining the Palette layer. Equivalent to new Integer(100).*/
  136.     public final static Integer PALETTE_LAYER = new Integer(100);
  137.     /** Convenience object defining the Modal layer. Equivalent to new Integer(200).*/
  138.     public final static Integer MODAL_LAYER = new Integer(200);
  139.     /** Convenience object defining the Popup layer. Equivalent to new Integer(300).*/
  140.     public final static Integer POPUP_LAYER = new Integer(300);
  141.     /** Convenience object defining the Drag layer. Equivalent to new Integer(400).*/
  142.     public final static Integer DRAG_LAYER = new Integer(400);
  143.     /** Convenience object defining the Frame Content layer. 
  144.       * This layer is normally only use to positon the contentPane and menuBar 
  145.       * components of JFrame.
  146.       * Equivalent to new Integer(-30000).
  147.       * @see JFrame
  148.       */
  149.     public final static Integer FRAME_CONTENT_LAYER = new Integer(-30000);
  150.  
  151.     /** Bound property */
  152.     public final static String LAYER_PROPERTY = "layeredContainerLayer";
  153.     // Hashtable to store layer values for non-JComponent components
  154.     private Hashtable componentToLayer;
  155.     private boolean optimizedDrawingPossible = true;
  156.  
  157.  
  158. //////////////////////////////////////////////////////////////////////////////
  159. //// Container Override methods 
  160. //////////////////////////////////////////////////////////////////////////////
  161.     /** Create a new JLayeredPane */
  162.     public JLayeredPane() {
  163.         setLayout(null);
  164.     }
  165.  
  166.     private void validateOptimizedDrawing() {
  167.         boolean layeredComponentFound = false;
  168.         synchronized(getTreeLock()) {
  169.             int i,d;
  170.             Integer layer = null;
  171.  
  172.             for(i=0,d=getComponentCount();i<d;i++) {
  173.                 layer = null;
  174.                 if(getComponent(i) instanceof JInternalFrame ||
  175.                    (getComponent(i) instanceof JComponent &&
  176.                     (layer = (Integer)((JComponent)getComponent(i)).getClientProperty(LAYER_PROPERTY)) != null)) {
  177.                     if(layer != null && layer.equals(FRAME_CONTENT_LAYER))
  178.                         continue;
  179.                     layeredComponentFound = true;
  180.                     break;
  181.                 }
  182.             }
  183.         }
  184.         
  185.         if(layeredComponentFound)
  186.             optimizedDrawingPossible = false;
  187.         else
  188.             optimizedDrawingPossible = true;
  189.     }
  190.     
  191.     protected void addImpl(Component comp, Object constraints, int index) {
  192.         int layer = DEFAULT_LAYER.intValue();
  193.         int pos;
  194.  
  195.         if(constraints instanceof Integer) {
  196.             layer = ((Integer)constraints).intValue();
  197.             setLayer(comp, layer);
  198.         } else
  199.             layer = getLayer(comp);
  200.  
  201.         pos = insertIndexForLayer(layer, index);
  202.         super.addImpl(comp, constraints, pos);
  203.         comp.validate();
  204.         comp.repaint();
  205.         validateOptimizedDrawing();
  206.     }
  207.  
  208.     /**
  209.      * Remove the indexed component from this pane.
  210.      * This is the absolute index, ignoring layers. 
  211.      *
  212.      * @param index  an int specifying the component to remove
  213.      * @see #getIndexOf
  214.      */
  215.     public void remove(int index) {
  216.         Component c = getComponent(index);
  217.         super.remove(index);
  218.         validateOptimizedDrawing();
  219.     }
  220.  
  221.     /**
  222.      * Returns false if components in the pane can overlap, which makes
  223.      * optimized drawing impossible. Otherwise, returns true.
  224.      *
  225.      * @return false if components can overlap, else true
  226.      * @see JComponent#isOptimizedDrawingEnabled
  227.      */
  228.     public boolean isOptimizedDrawingEnabled() {
  229.         return optimizedDrawingPossible;
  230.     }
  231.  
  232.  
  233. //////////////////////////////////////////////////////////////////////////////
  234. //// New methods for managing layers
  235. //////////////////////////////////////////////////////////////////////////////
  236.     /** Sets the layer property on a JComponent. This method does not cause
  237.       * any side effects like setLayer() (painting, add/remove, etc).
  238.       * Normally you should use the instance method setLayer(), in order to
  239.       * get the desired side-effects (like repainting).
  240.       * 
  241.       * @param c      the JComponent to move
  242.       * @param layer  an int specifying the layer to move it to
  243.       * @see #setLayer
  244.       */
  245.     public static void putLayer(JComponent c, int layer) {
  246.         /// MAKE SURE THIS AND setLayer(Component c, int layer, int position)  are SYNCED
  247.         Integer layerObj;
  248.  
  249.         layerObj = new Integer(layer);
  250.         c.putClientProperty(LAYER_PROPERTY, layerObj);
  251.     }
  252.  
  253.     /** Gets the layer property for a JComponent, it
  254.       * does not cause any side effects like setLayer(). (painting, add/remove, etc)
  255.       * Normally you should use the instance method getLayer().
  256.       * 
  257.       * @param c  the JComponent to check
  258.       * @return   an int specifying the component's layer
  259.       */
  260.     public static int getLayer(JComponent c) {
  261.         Integer i;
  262.         if((i = (Integer)c.getClientProperty(LAYER_PROPERTY)) != null)
  263.             return i.intValue();
  264.         return DEFAULT_LAYER.intValue();
  265.     }
  266.  
  267.     /** Convenience method that returns the first JLayeredPane which
  268.       * contains the specified component. Note that all JFrames have a 
  269.       * JLayeredPane at their root, so any component in a JFrame will
  270.       * have a JLayeredPane parent.
  271.       *
  272.       * @param c the Component to check
  273.       * @return the JLayeredPane that contains the component, or
  274.       *         null if no JLayeredPane is found in the component
  275.       *         hierarchy
  276.       * @see JFrame
  277.       * @see JRootPane
  278.       */
  279.     public static JLayeredPane getLayeredPaneAbove(Component c) {
  280.         if(c == null) return null;
  281.         
  282.         Component parent = c.getParent();
  283.         while(parent != null && !(parent instanceof JLayeredPane))
  284.             parent = parent.getParent();
  285.         return (JLayeredPane)parent;
  286.     }
  287.  
  288.     /** Sets the layer attribute on the specified component,
  289.       * making it the bottommost component in that layer.
  290.       * Should be called before adding to parent. 
  291.       * 
  292.       * @param c     the Component to set the layer for
  293.       * @param layer an int specifying the layer to set, where 
  294.       *              lower numbers are closer to the bottom
  295.       */
  296.     public void setLayer(Component c, int layer)  {
  297.         setLayer(c, layer, -1);
  298.     }
  299.  
  300.     /** Sets the layer attribute for the specified component and
  301.       * also sets its position within that layer.
  302.       * 
  303.       * @param c         the Component to set the layer for
  304.       * @param layer     an int specifying the layer to set, where 
  305.       *                  lower numbers are closer to the bottom
  306.       * @param position  an int specifying the position within the
  307.       *                  layer, where 0 is the topmost position and -1
  308.       *                  is the bottommost position
  309.       */
  310.     public void setLayer(Component c, int layer, int position)  {
  311.         Integer layerObj;
  312.         layerObj = getObjectForLayer(layer);
  313.  
  314.         if(layer == getLayer(c) && position == getPosition(c)) {
  315.             if(c instanceof JComponent)
  316.                 repaint(((JComponent)c)._bounds);
  317.             else
  318.                 repaint(c.getBounds());
  319.             return;
  320.         }
  321.         
  322.         /// MAKE SURE THIS AND putLayer(JComponent c, int layer) are SYNCED
  323.         if(c instanceof JComponent)
  324.             ((JComponent)c).putClientProperty(LAYER_PROPERTY, layerObj);
  325.         else
  326.             getComponentToLayer().put((Component)c, layerObj);
  327.         
  328.         if(c.getParent() == null || c.getParent() != this)      {
  329.             if(c instanceof JComponent)
  330.                 repaint(((JComponent)c)._bounds);
  331.             else
  332.                 repaint(c.getBounds());
  333.             return;
  334.         }
  335.  
  336.         // Remove the Component and re-add after re-setting the layer
  337.         // this is necessary now because I have no access to the
  338.         // components[] in Container, to reorder things.
  339.         remove(c);
  340.  
  341.         // ALERT passing NULL here for the constraints may be bad
  342.         // the current hacks to fix this smell bad right now. 
  343.         // Cannot override 
  344.         add(c, null, position);
  345.         if(c instanceof JComponent)
  346.             repaint(((JComponent)c)._bounds);
  347.         else
  348.             repaint(c.getBounds());
  349.     }
  350.  
  351.     /** 
  352.      * Returns the layer attribute for the specified Component.
  353.      * 
  354.      * @param c  the Component to check
  355.      * @return an int specifying the component's current layer
  356.      */
  357.     public int getLayer(Component c) {
  358.         Integer i;
  359.         if(c instanceof JComponent)
  360.             i = (Integer)((JComponent)c).getClientProperty(LAYER_PROPERTY);
  361.         else
  362.             i = (Integer)getComponentToLayer().get((Component)c);
  363.  
  364.         if(i == null)
  365.             return DEFAULT_LAYER.intValue();
  366.         return i.intValue();
  367.     }
  368.  
  369.     /** 
  370.      * Returns the index of the specified Component. 
  371.      * This is the absolute index, ignoring layers.
  372.      * Index numbers, like position numbers, have the topmost component
  373.      * at index zero. Larger numbers are closer to the bottom.
  374.      * 
  375.      * @param c  the Component to check
  376.      * @return an int specifying the component's index 
  377.      */
  378.     public int getIndexOf(Component c) {
  379.         int i, count;
  380.         
  381.         count = getComponentCount();    
  382.         for(i = 0; i < count; i++) {
  383.             if(c == getComponent(i))
  384.                 return i;
  385.         }
  386.         return -1;
  387.     }
  388.     /** 
  389.      * Moves the component to the top of the components in it's current layer
  390.      * (position 0).
  391.      *
  392.      * @param c the Component to move 
  393.      * @see #setPosition(Component, int) 
  394.      */
  395.     public void moveToFront(Component c) {
  396.         setPosition(c, 0);
  397.     }
  398.  
  399.     /** 
  400.      * Moves the component to the bottom of the components in it's current layer
  401.      * (position -1).
  402.      *
  403.      * @param c the Component to move 
  404.      * @see #setPosition(Component, int) 
  405.      */
  406.     public void moveToBack(Component c) {
  407.         setPosition(c, getComponentCountInLayer(getLayer(c)));
  408.     }
  409.  
  410.     /**
  411.      * Moves the component to <code>position</code> within it's current layer,
  412.      * where 0 is the topmost position within the layer and -1 is the bottommost
  413.      * position. 
  414.      * <p>
  415.      * <b>Note:</b> Position numbering is defined by java.awt.Container, and
  416.      * is the opposite of layer numbering. Lower position numbers are closer
  417.      * to the top (0 is topmost), and higher position numbers are closer to
  418.      * the bottom.
  419.      *
  420.      * @param c         the Component to move
  421.      * @param position  an int in the range -1..N-1, where N is the number of
  422.      *                  components in the component's current layer
  423.      */
  424.     public void setPosition(Component c, int position) {
  425.         setLayer(c, getLayer(c), position);
  426.     }
  427.  
  428.     /**
  429.      * Get the relative position of the component within its layer.
  430.      *
  431.      * @param c  the Component to check
  432.      * @return an int giving the component's position, where 0 is the
  433.      *         topmost position and the highest index value = the count
  434.      *         count of components at that layer, minus 1
  435.      *
  436.      * @see #getComponentCountInLayer
  437.      */
  438.     public int getPosition(Component c) {
  439.         int i, count, startLayer, curLayer, startLocation, pos = 0;
  440.         
  441.         count = getComponentCount();
  442.         startLocation = getIndexOf(c);
  443.  
  444.         if(startLocation == -1)
  445.             return -1;
  446.         
  447.         startLayer = getLayer(c);
  448.         for(i = startLocation - 1; i >= 0; i--) {
  449.             curLayer = getLayer(getComponent(i));               
  450.             if(curLayer == startLayer)
  451.                 pos++;
  452.             else
  453.                 return pos;
  454.         }
  455.         return pos;
  456.     }
  457.  
  458.     /** Returns the highest layer value from all current children.
  459.       * Returns 0 if there are no children.
  460.       *
  461.       * @return an int indicating the layer of the topmost component in the 
  462.       *         pane, or zero if there are no children
  463.       */
  464.     public int highestLayer() {
  465.         if(getComponentCount() > 0)
  466.             return getLayer(getComponent(0));           
  467.         return 0;
  468.     }
  469.  
  470.     /** Returns the lowest layer value from all current children.
  471.       * Returns 0 if there are no children.
  472.       *
  473.       * @return an int indicating the layer of the bottommost component in the 
  474.       *         pane, or zero if there are no children
  475.       */
  476.     public int lowestLayer() {
  477.         int count = getComponentCount();
  478.         if(count > 0)
  479.             return getLayer(getComponent(count-1));             
  480.         return 0;
  481.     }
  482.  
  483.     /**
  484.      * Returns the number of children currently in the specified layer.
  485.      *
  486.      * @param layer  an int specifying the layer to check
  487.      * @return an int specifying the number of components in that layer
  488.      */
  489.     public int getComponentCountInLayer(int layer) {
  490.         int i, count, curLayer;
  491.         int layerCount = 0;
  492.         
  493.         count = getComponentCount();
  494.         for(i = 0; i < count; i++) {
  495.             curLayer = getLayer(getComponent(i));               
  496.             if(curLayer == layer) {
  497.                 layerCount++;
  498.             /// Short circut the counting when we have them all
  499.             } else if(layerCount > 0 || curLayer < layer) {
  500.                 break;
  501.             }
  502.         }
  503.         
  504.         return layerCount;
  505.     }
  506.  
  507.     /**
  508.      * Returns an array of the components in the specified layer.
  509.      *
  510.      * @param layer  an int specifying the layer to check
  511.      * @return an array of Components contained in that layer
  512.      */
  513.     public Component[] getComponentsInLayer(int layer) {
  514.         int i, count, curLayer;
  515.         int layerCount = 0;
  516.         Component[] results;
  517.         
  518.         results = new Component[getComponentCountInLayer(layer)];
  519.         count = getComponentCount();
  520.         for(i = 0; i < count; i++) {
  521.             curLayer = getLayer(getComponent(i));               
  522.             if(curLayer == layer) {
  523.                 results[layerCount++] = getComponent(i);
  524.             /// Short circut the counting when we have them all
  525.             } else if(layerCount > 0 || curLayer < layer) {
  526.                 break;
  527.             }
  528.         }
  529.         
  530.         return results;
  531.     }
  532.  
  533.     /**
  534.      * Paints this JLayeredPane within the specified graphics context.
  535.      *
  536.      * @param g  the Graphics context within which to paint
  537.      */
  538.     public void paint(Graphics g) {
  539.         if(isOpaque()) {
  540.             Rectangle r = g.getClipBounds();
  541.             Color c = getBackground();
  542.             if(c == null)
  543.                 c = Color.lightGray;
  544.             g.setColor(c);
  545.             g.fillRect(r.x, r.y, r.width, r.height);
  546.         }
  547.         super.paint(g);
  548.     }
  549.  
  550. //////////////////////////////////////////////////////////////////////////////
  551. //// Implementation Details
  552. //////////////////////////////////////////////////////////////////////////////
  553.  
  554.     /**
  555.      * Returns the hashtable that maps components to layers.
  556.      *
  557.      * @return the Hashtable used to map components to their layers
  558.      */
  559.     protected Hashtable getComponentToLayer() {
  560.         if(componentToLayer == null)
  561.             componentToLayer = new Hashtable(4);
  562.         return componentToLayer;
  563.     }
  564.     
  565.     /**
  566.      * Returns the Integer object associated with a specified layer.
  567.      *
  568.      * @param layer an int specifying the layer
  569.      * @return an Integer object for that layer
  570.      */
  571.     protected Integer getObjectForLayer(int layer) {
  572.         Integer layerObj;
  573.         switch(layer) {
  574.         case 0:
  575.             layerObj = DEFAULT_LAYER;
  576.             break;
  577.         case 100:
  578.             layerObj = PALETTE_LAYER;
  579.             break;
  580.         case 200:
  581.             layerObj = MODAL_LAYER;
  582.             break;
  583.         case 300:
  584.             layerObj = POPUP_LAYER;
  585.             break;
  586.         case 400:
  587.             layerObj = DRAG_LAYER;
  588.             break;
  589.         default:
  590.             layerObj = new Integer(layer);
  591.         }
  592.         return layerObj;
  593.     }
  594.  
  595.     /** 
  596.      * Primative method that determines the proper location to
  597.      * insert a new child based on layer and position requests.
  598.      * 
  599.      * @param layer     an int specifying the layer
  600.      * @param position  an int specifying the position within the layer
  601.      * @return an int giving the (absolute) insertion-index
  602.      *
  603.      * @see #getIndexOf
  604.      */
  605.     protected int insertIndexForLayer(int layer, int position) {
  606.         int i, count, curLayer;
  607.         int layerStart = -1;
  608.         int layerEnd = -1;
  609.         
  610.         count = getComponentCount();
  611.         for(i = 0; i < count; i++) {
  612.             curLayer = getLayer(getComponent(i));               
  613.             if(layerStart == -1 && curLayer == layer) {
  614.                 layerStart = i;
  615.             }   
  616.             if(curLayer < layer ) {
  617.                 if(i == 0) { 
  618.                     // layer is greater than any current layer  
  619.                     // [ ASSERT(layer > highestLayer()) ] 
  620.                     layerStart = 0;
  621.                     layerEnd = 0;
  622.                 } else {
  623.                     layerEnd = i;
  624.                 }
  625.                 break;
  626.             }
  627.         }
  628.  
  629.         // layer requested is lower than any current layer
  630.         // [ ASSERT(layer < lowestLayer()) ] 
  631.         // put it on the bottom of the stack
  632.         if(layerStart == -1 && layerEnd == -1)
  633.             return count;
  634.  
  635.         // In the case of a single layer entry handle the degenerative cases
  636.         if(layerStart != -1 && layerEnd == -1)
  637.             layerEnd = count;
  638.         
  639.         if(layerEnd != -1 && layerStart == -1)
  640.             layerStart = layerEnd;
  641.         
  642.         // If we are adding to the bottom, return the last element
  643.         if(position == -1)
  644.             return layerEnd;
  645.         
  646.         // Otherwise make sure the requested position falls in the 
  647.         // proper range
  648.         if(position > -1 && layerStart + position <= layerEnd)
  649.             return layerStart + position;
  650.         
  651.         // Otherwise return the end of the layer
  652.         return layerEnd;
  653.     }
  654.  
  655.  
  656.     /**
  657.      * Returns a string representation of this JLayeredPane. This method 
  658.      * is intended to be used only for debugging purposes, and the 
  659.      * content and format of the returned string may vary between      
  660.      * implementations. The returned string may be empty but may not 
  661.      * be <code>null</code>.
  662.      * <P>
  663.      * Overriding paramString() to provide information about the
  664.      * specific new aspects of the JFC components.
  665.      * 
  666.      * @return  a string representation of this JLayeredPane.
  667.      */
  668.     protected String paramString() {
  669.         String optimizedDrawingPossibleString = (optimizedDrawingPossible ?
  670.                          "true" : "false");
  671.  
  672.     return super.paramString() +
  673.         ",optimizedDrawingPossible=" + optimizedDrawingPossibleString;
  674.     }
  675.  
  676. /////////////////
  677. // Accessibility support
  678. ////////////////
  679.  
  680.     /**
  681.      * Get the AccessibleContext associated with this JComponent
  682.      *
  683.      * @return the AccessibleContext of this JComponent
  684.      */
  685.     public AccessibleContext getAccessibleContext() {
  686.         if (accessibleContext == null) {
  687.             accessibleContext = new AccessibleJLayeredPane();
  688.         }
  689.         return accessibleContext;
  690.     }
  691.  
  692.     /**
  693.      * The class used to obtain the accessible role for this object.
  694.      * <p>
  695.      * <strong>Warning:</strong>
  696.      * Serialized objects of this class will not be compatible with
  697.      * future Swing releases.  The current serialization support is appropriate
  698.      * for short term storage or RMI between applications running the same
  699.      * version of Swing.  A future release of Swing will provide support for
  700.      * long term persistence.
  701.      */
  702.     protected class AccessibleJLayeredPane extends AccessibleJComponent {
  703.  
  704.         /**
  705.          * Get the role of this object.
  706.          *
  707.          * @return an instance of AccessibleRole describing the role of the 
  708.          * object
  709.          * @see AccessibleRole
  710.          */
  711.         public AccessibleRole getAccessibleRole() {
  712.             return AccessibleRole.LAYERED_PANE;
  713.         }
  714.     }
  715. }
  716.  
  717.  
  718.